package com.qinggeng.project.system.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinggeng.common.constant.Constants;
import com.qinggeng.common.enums.*;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.redenvelop.BigDecimalUtil;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.framework.config.mq.MQSendUtils;
import com.qinggeng.framework.config.mq.dto.*;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.framework.redis.RedisCache;
import com.qinggeng.framework.web.exception.GlobalExceptionHandler;
import com.qinggeng.project.api.dto.*;
import com.qinggeng.project.api.mapper.ApiMemberMapper;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.api.service.IApiMemberService;
import com.qinggeng.project.api.utils.OrdersCheckUtils;
import com.qinggeng.project.api.utils.RandomBargainAmountUtils;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.domain.vo.*;
import com.qinggeng.project.system.dto.OrderStatisticsDTO;
import com.qinggeng.project.system.dto.OrdersSingleGoodsReturnDTO;
import com.qinggeng.project.system.mapper.*;
import com.qinggeng.project.system.service.*;
import com.qinggeng.project.tool.pay.service.AliPayService;
import com.qinggeng.project.tool.pay.service.WxPayService;
import com.qinggeng.project.tool.sms.service.ISysSmsService;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.qinggeng.project.system.service.impl.GiftServiceImpl.OUT_PAY_TIME_KEY;

/**
 * 订单列Service业务层处理
 *
 * @author qinggeng
 * @date 2020-06-17
 */
@Service
public class OrdersServiceImpl implements IOrdersService {

    public static final String EVALUATE_OUT_TIME_KEY = "sys.orders.evalOutTime";

    public static final String AFFIRM_OUT_TIME_KEY = "sys.orders.affirmOutTime";

    private final static String KEEP_OF_GOODS="keepOfGoods:";


    @Resource
    private OrdersMapper ordersMapper;

    @Autowired
    private ISysConfigService sysConfigService;

    @Resource
    private OrdersAddressMapper ordersAddressMapper;

    @Resource
    private OrdersPointMapper ordersPointMapper;

    @Resource
    private OrdersGoodsMapper ordersGoodsMapper;

    @Resource
    private ApiMemberMapper apiMemberMapper;

    @Autowired
    private IOrdersCourierService ordersCourierService;

    @Autowired
    private AliPayService aliPayService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private IUserLocationService userLocationService;

    @Autowired
    private IUserConsumeService userConsumeService;


    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IShopService shopService;

    @Autowired
    private IGoodsKeepService goodsKeepService;

    @Autowired
    private IOrdersGoodsService ordersGoodsService;

    @Autowired
    private IOrdersGiftService ordersGiftService;


    @Autowired
    private IUserWalletService userWalletService;

    @Autowired
    private ISysSmsService smsService;

    @Autowired
    private IGoodsPercentService goodsPercentService;

    @Autowired
    private IGoodsActiviyService goodsActiviyService;

    @Autowired
    private OrdersDistService ordersDistService;


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisCache redisCache;

    @Resource
    private UserBeatMapper userBeatMapper;

    @Resource
    private UserBeatCountMapper userBeatCountMapper;

    @Autowired
    private MQSendUtils mqSendUtils;

    @Autowired
    private MQSendService mqSendService;

    @Resource
    private IDistributionPointService distributionPointService;

    @Autowired
    private IOrdersAddressService ordersAddressService;

    @Autowired
    private IOrdersPointService ordersPointService;

    @Autowired
    private OrdersCheckUtils ordersCheckUtils;

    @Resource
    private UserAccountMapper userAccountMapper;

    @Autowired
    private IUserAccountService userAccountService;


    @Autowired
    private ICourierService courierService;

    @Resource
    private ShareOrdersMapper shareOrdersMapper;
    @Autowired
    private IGoodsService goodsService;


    @Autowired
    private MemberService memberService;

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);


    /**
     * 查询订单列
     *
     * @param ordersId 订单列ID
     * @return 订单列
     */
    @Override
    public Orders selectOrdersById(Long ordersId) {
        return ordersMapper.selectOrdersById(ordersId);
    }

    @Override
    public Orders selectOrdersByIdAndUserId(Long ordersId, Long userId) {
        return ordersMapper.selectOrdersByIdAndUserId(ordersId, userId);
    }

    /**
     * 查询订单列列表
     *
     * @param orders 订单列
     * @return 订单列
     */
    @Override
    public List<Orders> selectOrdersList(Orders orders) {
        return ordersMapper.selectOrdersList(orders);
    }

    public List<Orders> listOrdersByTime(Orders orders){
        if(StringUtils.isNotEmpty(orders.getBeginTime())){
            orders.setBeginTime(orders.getBeginTime()+" 00:00:00");
        }
        if(StringUtils.isNotEmpty(orders.getEndTime())){
            orders.setEndTime(orders.getEndTime()+" 23:59:59");
        }
        return ordersMapper.listOrdersByTime(orders);
    }



    @Override
    public List<Orders> selectOrdersReturnList(Orders orders) {
        return ordersMapper.selectOrdersReturnList(orders);
    }

    @Override
    public List<OrdersSingleGoodsReturnVO> selectOrdersSingleGoodsReturnList(OrdersSingleGoodsReturnDTO dto) {
        List<OrdersSingleGoodsReturnVO> ordersSingleGoodsReturnVOS = ordersMapper.selectOrdersSingleGoodsReturnList(dto);
        for (OrdersSingleGoodsReturnVO ordersSingleGoodsReturnVO : ordersSingleGoodsReturnVOS) {
            int num = ordersSingleGoodsReturnVO.getGoodsNum();
            String goodsPrice = ordersSingleGoodsReturnVO.getGoodsPrice();
            String payMoney = BigDecimalUtil.multiply(new BigDecimal(num), new BigDecimal(goodsPrice)).setScale(2, BigDecimal.ROUND_DOWN).toString();
            ordersSingleGoodsReturnVO.setPayMoney(payMoney);
        }
        return ordersSingleGoodsReturnVOS;
    }

    @Override
    public boolean ordersDistAutoTake(String ordersNo) {
        return ordersMapper.ordersDistAutoTake(ordersNo) > 0;
    }

    /**
     * 新增订单列
     *
     * @param orders 订单列
     * @return 结果
     */
    @Override
    public int insertOrders(Orders orders) {
        orders.setCreateTime(DateUtils.getNowDate());
        int outTime = Integer.parseInt(sysConfigService.getConfigValue(OUT_PAY_TIME_KEY));
        Calendar outPayTime = Calendar.getInstance();
        outPayTime.setTime(orders.getCreateTime());
        outPayTime.add(Calendar.MINUTE, outTime);
        orders.setPayOutTime(outPayTime.getTime());
        return ordersMapper.insertOrders(orders);
    }

    /**
     * 修改订单列
     *
     * @param orders 订单列
     * @return 结果
     */
    @Override
    public int updateOrders(Orders orders) {
        orders.setUpdateTime(DateUtils.getNowDate());
        return ordersMapper.updateOrders(orders);
    }


    /**
     * 批量删除订单列
     *
     * @param ordersIds 需要删除的订单列ID
     * @return 结果
     */
    @Override
    public int deleteOrdersByIds(Long[] ordersIds) {
        return ordersMapper.deleteOrdersByIds(ordersIds);
    }

    /**
     * 删除订单列信息
     *
     * @param ordersId 订单列ID
     * @return 结果
     */
    @Override
    public int deleteOrdersById(Long ordersId) {
        return ordersMapper.deleteOrdersById(ordersId);
    }

    /**
     * 单商品下单
     *
     * @param distType      配送方式
     * @param ordersInfoDto
     * @param userId
     * @return
     */
    @Transactional
    @Override
    public Orders createOrders(String distType, AddOrdersInfoDto ordersInfoDto, Long userId) {

        Orders orders = new Orders(ordersInfoDto);
        orders.setDistType(distType);//配送方式
        orders.setUserId(userId);//用户ID

        if (ordersInfoDto.getOrdersType().equals(OrdersTypeEnum.捶一捶.getValue())) {
            orders.setDelFlag("2");
        }
        int rows=insertOrders(orders);
        if(rows<1){
            throw new CustomException("下单失败！");
        }
        //订单地址
        if (distType.equals(OrdersDistTypeEnum.配送.getValue())) {
            ordersAddressService.insertOrdersAddress(orders.getOrdersId(),ordersInfoDto.getAddress());
        }
        // 订单配送点信息保存到数据库中
        ordersPointService.insertOrdersPoint(orders.getOrdersId(),ordersInfoDto.getPoint().getId());

        //商品添加库存修改
        OrdersGoods ordersGoods = null;
        for (AddOrdersInfoGoodsDto goodsDto : ordersInfoDto.getGoodsList()) {
            GoodsKeep goodsKeep = goodsKeepService.selectGoodsKeepByGoodsId(goodsDto.getGoodsId(), ordersInfoDto.getShop().getId());
            if (goodsDto.getGoodsNum() > goodsKeep.getKeepNum()) {
                throw new CustomException(goodsDto.getGoodsName() + "已被抢光", ShowTypeEnum.用户.getValue());
            }


            ordersGoods = new OrdersGoods();
            ordersGoods.setOrdersId(orders.getOrdersId());
            ordersGoods.setGoodsName(goodsDto.getGoodsName());
            ordersGoods.setGoodsImg(goodsDto.getGoodsImg());
            if (OrdersTypeEnum.好友助力.getValue().equals(orders.getOrdersType())) {
                ordersGoods.setGoodsPrice(goodsDto.getGroupPrice());
            } else {
                ordersGoods.setGoodsPrice(goodsDto.getGoodsPrice());
            }
            ordersGoods.setGoodsNum(goodsDto.getGoodsNum());
            ordersGoods.setGoodsId(goodsDto.getGoodsId());
            ordersGoods.setAttributes(goodsDto.getAttributes());
            ordersGoods.setDiscountStatus(goodsDto.getDiscountStatus());
            ordersGoods.setDiscountPrice(goodsDto.getDiscountPrice());

            //获取商品提成百分比，并计算商品提成
            ordersGoods.setPercent(goodsDto.getPercent());
            ordersGoodsService.setProfitAndPercentage(goodsDto.getBuyPrice(),ordersGoods);
            ordersGoodsMapper.insertOrdersGoods(ordersGoods);

            //插入用户捶一捶记录
            if (ordersInfoDto.getOrdersType().equals(OrdersTypeEnum.捶一捶.getValue())) {

                //查询天与天连续捶的次数
                UserBeatCount userBeatCount = userBeatCountMapper.selectUserBeatCountByUserId(ApiUtils.getUserId());
                //查询昨天是否捶成功过
                int count = userBeatMapper.selectUserBeatByUserId(ApiUtils.getUserId());

                if (count > 0) {
                    //存在就更新记录 次数加1
                    if (userBeatCount == null) {
                        throw new CustomException("用户昨天的记录不存在,无法加次数");
                    }
                    //当前日期
                    String dateNow = DateUtils.getDate();
                    //更新日期
                    String dateOld = DateUtils.dateTime(userBeatCount.getUpdateTime());
                    //昨天捶过且今天没有更新过
                    if (!dateNow.equals(dateOld)) {
                        userBeatCountMapper.updateUserBeatCountAdd(ApiUtils.getUserId());
                        userBeatCount.setBeatCount(userBeatCount.getBeatCount() + 1);
                    }
                } else {
                    //如果不存在记录就插入记录
                    if (userBeatCount == null) {
                        userBeatCount = new UserBeatCount();
                        userBeatCount.setUserId(ApiUtils.getUserId());
                        userBeatCount.setBeatCount(0);
                        userBeatCount.setUpdateTime(DateUtils.getNowDate());
                        userBeatCountMapper.insertUserBeatCount(userBeatCount);
                    } else {
                        //如果剩余次数>0,次数减1
                        //当前日期
                        String dateNow = DateUtils.getDate();
                        //更新日期
                        String dateOld = DateUtils.dateTime(userBeatCount.getUpdateTime());
                        //每天连续捶的次数大于0,且今天没有更新过
                        if (userBeatCount.getBeatCount() > 0 && !dateNow.equals(dateOld)) {
                            userBeatCountMapper.updateUserBeatCountDre(ApiUtils.getUserId());
                            userBeatCount.setBeatCount(userBeatCount.getBeatCount() - 1);
                        }
                    }
                }
                //添加已捶商品记录
                ActivityGoodsDto activityGoodsDto = goodsActiviyService.selectGooodsActivityDtoBy(ordersGoods.getGoodsId());
                int beatNum = activityGoodsDto.getGroupNum();
                //从字典表获取捶一捶活动参数
                JSONObject jsonObject = JSONObject.parseObject(sysConfigService.selectConfigByKey("sys.beat.data").toString());
                if (userBeatCount.getBeatCount() > 0) {
                    //根据比例设置所捶人数
                    //ceo第二次连续捶所需的比例
                    beatNum += new BigDecimal(activityGoodsDto.getGroupNum().toString()).multiply(new BigDecimal(jsonObject.getString("ceo"))).intValue() + userBeatCount.getBeatCount();
                }
                //捶一捶各个人所需要捶的价格
                List<String> random = RandomBargainAmountUtils.randomPrice(activityGoodsDto.getGoodsPrice(), beatNum);


                //将集合存入redis中并设置过期时间为24小时
                redisCache.setCacheList("ORDERS_ID:" + orders.getOrdersId(), random);
                redisTemplate.expire("ORDERS_ID:" + orders.getOrdersId(), Long.parseLong(jsonObject.getString("time")), TimeUnit.SECONDS);

                //存入总金额
                redisCache.setCacheObject("ORDERS_PRICE:" + orders.getOrdersId(), activityGoodsDto.getGoodsPrice(), Integer.parseInt(jsonObject.getString("time")), TimeUnit.SECONDS);

                //插入记录
                UserBeat userBeat = new UserBeat();
                userBeat.setUserId(ApiUtils.getUserId());
                userBeat.setOrdersId(orders.getOrdersId());
                userBeat.setGoodsId(goodsDto.getGoodsId());
                userBeat.setGoodsName(goodsDto.getGoodsName());
                userBeat.setGoodsImg(goodsDto.getGoodsImg());
                userBeat.setBeatSum(beatNum);
                //订单刚生成 捶成记录为进行中
                userBeat.setBeatInto("2");
                //是否领取 未领取
                userBeat.setReceive("0");
                userBeat.setCreateTime(DateUtils.getNowDate());
                //设置过期时间
                userBeat.setBeatOutTime(new Date(Instant.now().toEpochMilli() + redisCache.getExpire("ORDERS_ID:" + orders.getOrdersId()) * 1000));
                userBeatMapper.insertUserBeat(userBeat);

                //发送捶一捶延时消息
                MessageBeatDTO messageBeatDTO = new MessageBeatDTO();
                //捶一捶ID
                messageBeatDTO.setId(userBeat.getId());
                messageBeatDTO.setMessageId(IdUtil.getSnowflake(1l, 1l).nextId());
                messageBeatDTO.setType(MQTypeEnum.BEAT_FAIL_HANDLE.getType());
                messageBeatDTO.setDelayTime(Long.parseLong(jsonObject.getString("time")));
                mqSendUtils.sendDelayMessage(messageBeatDTO, Long.parseLong(jsonObject.getString("time")));
            }


            //减少库存

            int r = goodsKeepService.subKeepNum(ordersGoods.getGoodsId(), orders.getShopId(), ordersGoods.getGoodsNum());
            if (r < 1) {
                //高并发下超量下单的问题
                throw new CustomException("已被抢光", ShowTypeEnum.用户.getValue());
            }
        }

        //订单支付超时延时任务
        mqSendService.sendPayOutTimeDelayMessage(orders.getOrdersNo());

        return orders;
    }

    /**
     * 拼团下单
     *
     * @param distType      配送方式
     * @param ordersInfoDto
     * @param userId
     * @return
     */
    @SneakyThrows
    @Transactional
    @Override
    public Orders createOrders1(String distType, AddOrdersInfoDto ordersInfoDto, Long userId, List<FavorableDTO> favorableDTOS) {
        Orders orders = new Orders(ordersInfoDto);
        orders.setDistType(distType);//配送方式
        orders.setUserId(userId);//用户ID
        orders.setOrdersType(ordersInfoDto.getOrdersType());//订单类型
        int rows=insertOrders(orders);
        if(rows<1){
            throw new CustomException("下单失败");
        }


        if (distType.equals(OrdersDistTypeEnum.配送.getValue())) {
            ordersAddressService.insertOrdersAddress(orders.getOrdersId(),ordersInfoDto.getAddress());
        }

        if (!CollectionUtils.isEmpty(favorableDTOS)) {
            //订单商品设置总优惠价格
            for (AddOrdersInfoGoodsDto goodsDto : ordersInfoDto.getGoodsList()) {
                for (FavorableDTO favorableDTO : favorableDTOS) {
                    if (favorableDTO.getGoodsId().equals(goodsDto.getGoodsId())) {
                        if (goodsDto.getDiscountPrice() == null) {
                            goodsDto.setDiscountPrice(new BigDecimal("0"));
                        }
                        goodsDto.setDiscountStatus(DiscountStatusEnum.YES.getType());
                        goodsDto.setDiscountPrice(goodsDto.getDiscountPrice().add(favorableDTO.getPrice()));
                    }
                }
            }
        }


        // 订单配送点信息保存到数据库中
        ordersPointService.insertOrdersPoint(orders.getOrdersId(),ordersInfoDto.getPoint().getId());

        //判断用户是不是会员
        Integer  memberCode= memberService.isVip(userId);
        //设置订单展示价格
        boolean bl=MemberEnum.MEMBER.getKey().equals(memberCode);
        //商品添加库存修改
        OrdersGoods ordersGoods;
        for (AddOrdersInfoGoodsDto goodsDto : ordersInfoDto.getGoodsList()) {
            GoodsKeep goodsKeep = goodsKeepService.selectGoodsKeepByGoodsId(goodsDto.getGoodsId(), ordersInfoDto.getShop().getId());
            if (goodsDto.getGoodsNum() > goodsKeep.getKeepNum()) {
                throw new CustomException(goodsDto.getGoodsName() + "已被抢光", ShowTypeEnum.用户.getValue());
            }
            ordersGoods = new OrdersGoods();
            ordersGoods.setOrdersId(orders.getOrdersId());
            ordersGoods.setGoodsName(goodsDto.getGoodsName());
            ordersGoods.setGoodsImg(goodsDto.getGoodsImg());
            if (bl){
                ordersGoods.setGoodsPrice(goodsDto.getVipPrice());
            }else {
                ordersGoods.setGoodsPrice(goodsDto.getGroupPrice());
            }
            ordersGoods.setGoodsNum(goodsDto.getGoodsNum());
            ordersGoods.setGoodsId(goodsDto.getGoodsId());
            ordersGoods.setAttributes(goodsDto.getAttributes());
            ordersGoods.setCourierId(goodsDto.getCourierId());
            if (goodsDto.getDiscountPrice() != null) {
                ordersGoods.setDiscountPrice(goodsDto.getDiscountPrice());
            }
            if (goodsDto.getDiscountStatus() != null){
                ordersGoods.setDiscountStatus(goodsDto.getDiscountStatus());
            }

            ordersGoods.setPercent(goodsDto.getPercent());

            ordersGoodsService.setProfitAndPercentage(goodsDto.getBuyPrice(),ordersGoods);

            ordersGoodsMapper.insertOrdersGoods(ordersGoods);

            int r = goodsKeepService.subKeepNum(ordersGoods.getGoodsId(), orders.getShopId(), ordersGoods.getGoodsNum());
            if (r < 1) {
                //高并发下超量下单的问题
                throw new CustomException("已被抢光", ShowTypeEnum.用户.getValue());
            }
        }

        //订单支付超时延时任务
        mqSendService.sendPayOutTimeDelayMessage(orders.getOrdersNo());

        return orders;
    }


    private void sendReduceKeepAsynMessage(Long goodsId,Long shopId,Integer goodsNum,Integer keepNum){
        MessageGoodsKeepReduceDTO messageGoodsKeepReduceDTO = new MessageGoodsKeepReduceDTO();
        messageGoodsKeepReduceDTO.setType(MQTypeEnum.GOOD_KEEP_REDUCE.getType());
        messageGoodsKeepReduceDTO.setGoodsId(goodsId);
        messageGoodsKeepReduceDTO.setShopId(shopId);
        messageGoodsKeepReduceDTO.setGoodsNum(goodsNum);
        messageGoodsKeepReduceDTO.setKeepNum(keepNum);
        mqSendUtils.sendAsynMessage(messageGoodsKeepReduceDTO);
    }

    @Override
    public Orders selectOrdersByOrdersNo(String ordersNo) {
        return ordersMapper.selectOrdersByOrdersNo(ordersNo);
    }

    @Override
    public int selectPayStatusSuccess(String ordersNo) {
        return ordersMapper.selectPayStatusSuccess(ordersNo);
    }

    @Override
    public int selectOrdersCount(Orders where) {
        return ordersMapper.selectOrdersCount(where);
    }

    @Override
    public List<OrdersDistDto> selectOrdersDiscDtoList(Integer status, Float lng, Float lat, Long pointId) {
        List<OrdersDistDto> ordersDistDtoList = ordersMapper.selectOrdersDiscDtoList(status, lng, lat, pointId);
        List<Long> ordersIdList = Lists.newArrayList();
        for (OrdersDistDto ordersDistDto : ordersDistDtoList) {
            ordersIdList.add(ordersDistDto.getOrdersId());
        }
        List<OrdersGoods> ordersGoodsList = null;
        List<OrdersGift> ordersGiftList = null;
        if (!CollectionUtils.isEmpty(ordersIdList)){
            ordersGoodsList = ordersGoodsMapper.selectOrderGoodListByOrdersIds(ordersIdList);
            ordersGiftList = ordersGiftService.selectOrdersGiftListByOrdersIds(ordersIdList);
        }
        List<OrdersGoods> goodsList;
        List<OrdersGift> giftList;
        BigDecimal totalPrice;
        if (!CollectionUtils.isEmpty(ordersGoodsList) && !CollectionUtils.isEmpty(ordersDistDtoList)){
            for (OrdersDistDto ordersDistDto : ordersDistDtoList) {
                goodsList = Lists.newArrayList();
                totalPrice = BigDecimal.ZERO;
                for (OrdersGoods ordersGoods : ordersGoodsList) {
                    if (ordersDistDto.getOrdersId().equals(ordersGoods.getOrdersId())){
                        goodsList.add(ordersGoods);
                        totalPrice = totalPrice.add(ordersGoods.getGoodsPrice().multiply(new BigDecimal(ordersGoods.getGoodsNum().toString())));
                    }
                }
                ordersDistDto.setOrdersGoodsList(goodsList);
                totalPrice = totalPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
                ordersDistDto.setTotalPrice(totalPrice);

            }
        }
        if (!CollectionUtils.isEmpty(ordersGiftList) && !CollectionUtils.isEmpty(ordersDistDtoList)){
            for (OrdersDistDto ordersDistDto : ordersDistDtoList) {
                giftList = Lists.newArrayList();
                for (OrdersGift ordersGift : ordersGiftList) {
                    if (ordersDistDto.getOrdersId().equals(ordersGift.getOrdersId())){
                        giftList.add(ordersGift);
                    }
                }
                ordersDistDto.setOrdersGiftList(giftList);
            }
        }

        for (OrdersDistDto ordersDistDto : ordersDistDtoList) {
            ordersDistDto.setStatus(status);
            //计算订单的商品提成
            BigDecimal ordersPercentage=ordersGoodsService.getOrdersPercentageByOrdersId(ordersDistDto.getOrdersId());
            //订单提成=配送费+商品提成
            ordersDistDto.setPercentage(ordersDistDto.getDistPrice().add(ordersPercentage));
        }
        return ordersDistDtoList;
    }

    @Override
    public void notifyCallback(String outTradeNo, String payType) {
        Orders orders = selectOrdersByOrdersNo(outTradeNo);
        if (orders == null) {
            throw new CustomException("订单号不存在");
        }
        if (orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("重复支付回调信息");
        }

        orders.setPayStatus(CommonEnum.STATUS_20.getValue());
        orders.setPayTime(DateUtils.getNowDate());
        orders.setPayType(payType);
        //代付的订单直接为发货状态
        orders.setDistShopOutTime(getDistShopOutTime(orders));
        if (orders.getOrdersType().equals(OrdersTypeEnum.代付.getValue())){
            orders.setPrintStatus(PrintStatusEnum.已打印.getStatus());
            orders.setShipStatus(CommonEnum.STATUS_20.getValue());
        }
        //添加商户超时接单时间
        ordersMapper.updateOrders(orders);

        //消费记录
        userConsumeService.addUserConsume(orders.getUserId(), orders.getPayPrice(), orders.getOrdersId(), UserConsumeEnum.订单支付, "-");

    }

    @Transactional
    @Override
    public int updateOrdersState(Orders orders) {
        //接单处理
        orders.setDistShopTime(DateUtils.getNowDate());
        SysUser oldUser = apiMemberMapper.selectMemberById(orders.getUserId());
        Shop shop = shopService.selectShopById(orders.getShopId());
        //拒绝退款处理
        if (orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue()) && orders.getDistShopStatus().equals(CommonEnum.STATUS_30.getValue())) {
            try {
                if (orders.getPayType().equals(PayTypeEnum.ALIPAY.getCode())) {
                    aliPayService.refund(orders.getOrdersNo(), orders.getPayPrice());
                } else if (orders.getPayType().equals(PayTypeEnum.WXPAY.getCode())) {
                    wxPayService.refund(orders.getOrdersNo(), orders.getPayPrice());
                } else {
                    throw new CustomException("退款失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new CustomException("退款失败");
            }

            //消费记录
            userConsumeService.addUserConsume(orders.getUserId(), orders.getPayPrice(), orders.getOrdersId(), UserConsumeEnum.订单退款, "+");

            orders.setPayStatus(CommonEnum.STATUS_40.getValue());
            orders.setStatus(OrdersStatusEnum.已关闭.getValue());

////            //推送消息
//            PushPayload pushPayload1 = MessagePushUtils.push(Audience.alias(oldUser.getPhonenumber()), "商家未接单，已退款", null);
////            //TODO（开始推送）
//            MessagePushUtils.sendPushTryCatch(JpushUserEnum.客户端,pushPayload1);
        }
        if (orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue()) && orders.getDistShopStatus().equals(CommonEnum.STATUS_20.getValue())) {
            //添加商户超时接单时间
            Calendar distOutTime = Calendar.getInstance();
            distOutTime.setTime(DateUtils.getNowDate());
            distOutTime.add(Calendar.MINUTE, Integer.parseInt(sysConfigService.selectConfigByKey("sys.orders.distOutTime").toString()));
            orders.setDistOutTime(distOutTime.getTime());


//            //推送消息
//            PushPayload pushPayload1 = MessagePushUtils.push(Audience.alias(oldUser.getPhonenumber()), "商家已接单，待骑手接单", null);
//            //TODO（开始推送）
//            MessagePushUtils.sendPushTryCatch(JpushUserEnum.客户端,pushPayload1);
//            //推送消息
//            PushPayload pushPayload2 = MessagePushUtils.push(Audience.tag(ApiUtils.DEFAULT_ROLE_COURIER+shop.getInviteCode()), "有新的订单来了",null);
//            //TODO（开始推送）
//            MessagePushUtils.sendPushTryCatch(JpushUserEnum.骑手端,pushPayload2);
        }
        return updateOrders(orders);
    }

    @Transactional
    @Override
    public void discOrdersTake(Long ordersId, Long userId, Float lng, Float lat) {
        Orders orders = ordersMapper.selectOrdersById(ordersId);
        if (orders == null) {
            throw new CustomException("订单不存在");
        }
        if (!orders.getStatus().equals(OrdersStatusEnum.进行中.getValue())) {
            throw new CustomException("订单状态异常");
        }
        if (!orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("订单支付异常");
        }
        if (!orders.getDistShopStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("店铺接单状态异常");
        }
        if (!orders.getDistStatus().equals(CommonEnum.STATUS_10.getValue())) {
            throw new CustomException("订单已被接单", -101);
        }
        //接单数据
        SysUser sysUser = apiMemberMapper.selectMemberById(userId);
        SysUser oldUser = apiMemberMapper.selectMemberById(orders.getUserId());

        if (sysUser.getWorkStatus().equals(CommonEnum.STATUS_10.getValue())) {
            throw new CustomException("当前工作状态无法接单");
        }

        //订单状态变更
        orders.setDistStatus(CommonEnum.STATUS_20.getValue());
        orders.setDistTime10(DateUtils.getNowDate());
        updateOrders(orders);

        OrdersCourier ordersCourier = new OrdersCourier();
        ordersCourier.setCourierId(userId);
        ordersCourier.setAvatar(sysUser.getAvatar());
        ordersCourier.setPhone(sysUser.getPhonenumber());
        ordersCourier.setNickName(sysUser.getNickName());
        ordersCourier.setOrdersId(ordersId);
        ordersCourier.setLng(lng);
        ordersCourier.setLat(lat);
        ordersCourierService.insertOrdersCourier(ordersCourier);

        //添加接单位置
        userLocationService.insertUserLocation(new UserLocation(userId, lng, lat));


//        //发送消息
//        UserMessage userMessage = new UserMessage();
//        userMessage.setMessageType(MessageTypeEnum.订单消息.getValue());
//        userMessage.setUserId(orders.getUserId());
//        userMessage.setFkId(ordersId);
//        userMessage.setFkMark("您的订单正在配送");
//        userMessageService.insertUserMessage(userMessage);
//
//        //推送消息
//        PushPayload pushPayload1 = MessagePushUtils.push(Audience.alias(oldUser.getPhonenumber()), "骑手已接单",null);
//        //TODO（开始推送）
//        MessagePushUtils.sendPushTryCatch(JpushUserEnum.客户端,pushPayload1);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized  void discOrdersAckTake(String ordersNo, Long userId) {
        Orders orders = ordersMapper.selectOrdersByOrdersNo(ordersNo);
        if (orders == null) {
            throw new CustomException("订单不存在，无法取货", ShowTypeEnum.用户.getValue());
        }

        if (!orders.getStatus().equals(OrdersStatusEnum.进行中.getValue())) {
            throw new CustomException("订单状态异常");
        }
        if (!orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("订单未支付，无法取货", ShowTypeEnum.用户.getValue());
        }
        if (!orders.getDistShopStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("店铺未接单，无法取货", ShowTypeEnum.用户.getValue());
        }
        if (!orders.getShipStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("订单未发货，无法取货", ShowTypeEnum.用户.getValue());
        }

        if (orders.getDistStatus().equals(OrdersDistStatusEnum.配送中.getValue())) {
            throw new CustomException("订单已取货，请勿重复操作", ShowTypeEnum.用户.getValue());
        }

        if (!orders.getDistStatus().equals(OrdersDistStatusEnum.待取货.getValue())) {
            throw new CustomException("配送状态异常");
        }

        //订单状态变更
        orders.setDistStatus(OrdersDistStatusEnum.配送中.getValue());
        orders.setDistTime20(DateUtils.getNowDate());
        int rows=this.updateOrders(orders);
        if(rows<1){
            log.error(ordersNo+"订单状态变更失败");
            throw new CustomException("订单状态变更失败");
        }

        //确认取货变更
        OrdersCourier ordersCourier = ordersCourierService.selectOrdersCourierByOrdersId(orders.getOrdersId());
        if (ordersCourier != null) {
            ordersCourier.setStatus(CommonEnum.STATUS_20.getValue());
            ordersCourierService.updateOrdersCourier(ordersCourier);
        }
            BigDecimal pointPrice =BigDecimal.ZERO;
            BigDecimal percentage =BigDecimal.ZERO;
        try {
            //添加配送费收益
            pointPrice= ordersDistService.getPointPrice(orders);
            if (null==pointPrice){
                log.error("商品配送费用{}出错",pointPrice);
                throw new CustomException("配送费:pointPrice"+pointPrice+"异常");
            }
            //计算订单的提成收益
            percentage=ordersGoodsService.getOrdersPercentageByOrdersId(orders.getOrdersId());
            percentage=percentage.add(pointPrice);
            log.info("orderId {} 自提点佣金 {} 配送费 {}",orders.getOrdersId(),percentage.toString(),pointPrice);
            if (OrdersTypeEnum.代付.getValue().equals(orders.getOrdersType())){
                percentage=BigDecimal.ZERO;
            }
            ordersMapper.updateOrdersPointCommission(orders.getOrdersId(),pointPrice.toString(),percentage.toString());

        } catch (Exception e) {
            log.error(ordersNo+"计算配送点收益失败",e);
            throw new CustomException("计算配送点收益失败");
        }
         Courier courier = courierService.getCourierByOrdersId(orders.getOrdersId());
        if (null ==courier){
            throw new CustomException("配送点是空");
        }
        String phonenumber=courier.getPhonenumber();
        if (StringUtils.isEmpty(phonenumber)){
            throw new CustomException("果果专员手机号:"+courier.getUserId()+"为空");
        }
        Long  gsdUserId=sysUserService.selectUserIdByPhoneNumberAndUserType(phonenumber,UserTypeEnum.MEMBER.getCode());
        if (null==gsdUserId){
            throw new CustomException("果舒达用户id为:"+gsdUserId+"为空");
        }
        if (orders.getDistType().equals(OrdersDistTypeEnum.自取.getValue())) {
            //发送到货提醒短信
            try {
                smsService.sendArriveNotice(orders.getOrdersNo());
            } catch (Exception e) {

            }
        }
        //发送订单消息推送
        //发送消息，保存
        MessageOrdersMessageDTO ordersMessageDTO = new MessageOrdersMessageDTO();
        ordersMessageDTO.setType(MQTypeEnum.ORDERS_MESSAGE_JPUSH.getType());
        ordersMessageDTO.setUserType(UserTypeEnum.MEMBER.getCode());
        ordersMessageDTO.setOrdersNo(ordersNo);
        ordersMessageDTO.setMark("订单到货通知");
        ordersMessageDTO.setMessage("尊敬的用户,您的订单" + ordersNo + "已到达自提点!");
        mqSendUtils.sendAsynMessage(ordersMessageDTO);
        log.info("orderId: {} 收益为 {}",orders.getOrdersId(),percentage);
        if (percentage.compareTo(BigDecimal.ZERO)>0) {
            userAccountService.checkFilterUserAccount(gsdUserId);
            UserAccount userAccount = new UserAccount();
            userAccount.setUserId(gsdUserId);
            userAccount.setAccount(percentage);
            userAccountMapper.addUserAccountMoney(userAccount);
            MessageOrderCommissionDTO dto = new MessageOrderCommissionDTO();
            dto.setUserId(gsdUserId);
            dto.setMoney(percentage.toString());
            dto.setType(MQTypeEnum.ORDER_COMMISSION_ACCOUNT.getType());
            mqSendUtils.sendAsynMessage(dto);
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void discOrdersAckTake(String ordersNo, Long userId, Long pointId) {
        Orders orders = ordersMapper.selectOrdersByOrdersNo(ordersNo);
        if (orders == null) {
            throw new CustomException("订单不存在，无法取货", ShowTypeEnum.用户.getValue());
        }

        if (!orders.getStatus().equals(OrdersStatusEnum.进行中.getValue())) {
            throw new CustomException("订单状态异常");
        }
        if (!orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("订单未支付，无法取货", ShowTypeEnum.用户.getValue());
        }
        if (!orders.getDistShopStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("店铺未接单，无法取货", ShowTypeEnum.用户.getValue());
        }
        if (!orders.getShipStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("订单未发货，无法取货", ShowTypeEnum.用户.getValue());
        }

        if (orders.getDistStatus().equals(OrdersDistStatusEnum.配送中.getValue())) {
            throw new CustomException("订单已取货，请勿重复操作", ShowTypeEnum.用户.getValue());
        }

        if (!orders.getDistStatus().equals(OrdersDistStatusEnum.待取货.getValue())) {
            throw new CustomException("配送状态异常");
        }

        //订单状态变更
        orders.setDistStatus(OrdersDistStatusEnum.配送中.getValue());
        orders.setDistTime20(DateUtils.getNowDate());
        int rows=this.updateOrders(orders);
        if(rows<1){
            log.error(ordersNo+"订单状态变更失败");
            throw new CustomException("订单状态变更失败");
        }

        //确认取货变更
        OrdersCourier ordersCourier = ordersCourierService.selectOrdersCourierByOrdersId(orders.getOrdersId());
        if (ordersCourier != null) {
            ordersCourier.setStatus(CommonEnum.STATUS_20.getValue());
            ordersCourierService.updateOrdersCourier(ordersCourier);
        }
        BigDecimal pointPrice =BigDecimal.ZERO;
        BigDecimal percentage =BigDecimal.ZERO;
        try {
            //添加配送费收益
            pointPrice= ordersDistService.getPointPrice(orders);
            if (null==pointPrice){
                throw new CustomException("配送费:pointPrice"+pointPrice+"异常");
            }
            //计算订单的提成收益
            ordersGoodsService.getOrdersPercentageByOrdersId(orders.getOrdersId());
            percentage=percentage.add(pointPrice);
        } catch (Exception e) {
            log.error(ordersNo+"计算配送点收益失败");
            throw new CustomException("计算配送点收益失败");
        }
        if (null==pointId){
            throw new CustomException("传递参数pointId为空");
        }
        Courier courier = courierService.getCourierByOrdersId(orders.getOrdersId());
        if (null ==courier){
            throw new CustomException("配送点是空");
        }
        String phonenumber=courier.getPhonenumber();
        if (StringUtils.isEmpty(phonenumber)){
            throw new CustomException("果果专员手机号:"+courier.getUserId()+"为空");
        }
        Long  gsdUserId=sysUserService.selectUserIdByPhoneNumberAndUserType(phonenumber,UserTypeEnum.MEMBER.getCode());
        if (null==gsdUserId){
            throw new CustomException("果舒达用户id为:"+gsdUserId+"为空");
        }
        if (orders.getDistType().equals(OrdersDistTypeEnum.自取.getValue())) {
            //发送到货提醒短信
            try {
                smsService.sendArriveNotice(orders.getOrdersNo());
            } catch (Exception e) {

            }
        }
        //发送订单消息推送
        //发送消息，保存
        MessageOrdersMessageDTO ordersMessageDTO = new MessageOrdersMessageDTO();
        ordersMessageDTO.setType(MQTypeEnum.ORDERS_MESSAGE_JPUSH.getType());
        ordersMessageDTO.setUserType(UserTypeEnum.MEMBER.getCode());
        ordersMessageDTO.setOrdersNo(ordersNo);
        ordersMessageDTO.setMark("订单到货通知");
        ordersMessageDTO.setMessage("尊敬的用户,您的订单" + ordersNo + "已到达自提点!");
        mqSendUtils.sendAsynMessage(ordersMessageDTO);
        log.info("orderId: {} 收益为 {}",orders.getOrdersId(),percentage);
        if (percentage.compareTo(BigDecimal.ZERO)>0) {
            userAccountService.checkFilterUserAccount(gsdUserId);
            UserAccount userAccount = new UserAccount();
            userAccount.setUserId(gsdUserId);
            userAccount.setAccount(percentage);
            userAccountMapper.addUserAccountMoney(userAccount);
            MessageOrderCommissionDTO dto = new MessageOrderCommissionDTO();
            dto.setUserId(gsdUserId);
            dto.setMoney(percentage.toString());
            dto.setType(MQTypeEnum.ORDER_COMMISSION_ACCOUNT.getType());
            mqSendUtils.sendAsynMessage(dto);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void discOrdersAckSend(String ordersNo, Long userId, String receiver) {
        Orders orders = ordersMapper.selectOrdersByOrdersNo(ordersNo);
        //检验订单支付状态
        ordersCheckUtils.checkOrdersPayStatus(orders);
        if (!orders.getDistShopStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("店铺接单状态异常");
        }
        if (!orders.getDistStatus().equals(CommonEnum.STATUS_30.getValue())) {
            throw new CustomException("配送状态异常");
        }
        try {
            //订单状态变更
            orders.setDistStatus(CommonEnum.STATUS_40.getValue());
            orders.setDistTime30(DateUtils.getNowDate());
            //设置签收人
            if (StringUtils.isEmpty(receiver)) {
                if (orders.getDistType().equals(OrdersDistTypeEnum.配送.getValue())) {
                    OrdersAddress address = ordersAddressMapper.selectOrdersAddressByOrdersId(orders.getOrdersId());
                    if (address != null && StringUtils.isNotEmpty(address.getConsignee())) {
                        receiver = address.getConsignee();
                    }
                }
                if (orders.getDistType().equals(OrdersDistTypeEnum.自取.getValue())) {
                    SysUser user = apiMemberMapper.selectMemberById(orders.getUserId());
                    if (user != null && StringUtils.isNotEmpty(user.getNickName())) {
                        receiver = user.getNickName();
                    }
                }
            }
            orders.setReceiver(receiver);

            int rows = updateOrders(orders);
            if (rows < 1) {
                log.error("变更订单配送状态失败");
                throw new CustomException("变更订单配送状态失败");
            }
            try {
                //确认取货变更
                OrdersCourier ordersCourier = ordersCourierService.selectOrdersCourierByOrdersId(orders.getOrdersId());
                ordersCourier.setStatus(CommonEnum.STATUS_30.getValue());
                ordersCourierService.updateOrdersCourier(ordersCourier);
            } catch (Exception e) {
                log.error("变更订单骑手状态失败");
            }



            //发送消息
            //发送消息，保存
            MessageOrdersMessageDTO ordersMessageDTO = new MessageOrdersMessageDTO();
            ordersMessageDTO.setType(MQTypeEnum.ORDERS_MESSAGE_JPUSH.getType());
            ordersMessageDTO.setUserType(UserTypeEnum.MEMBER.getCode());
            ordersMessageDTO.setOrdersNo(ordersNo);
            ordersMessageDTO.setMark("订单签收提醒");
            ordersMessageDTO.setMessage("尊敬的用户,您的订单" + ordersNo + "已确认送达!");
            mqSendUtils.sendAsynMessage(ordersMessageDTO);
        } catch (Exception e) {
            throw new CustomException("确认送达失败", ShowTypeEnum.用户.getValue());
        }

    }

    @Override
    public int selectOrdersDiscDtoCount(Long pointId, Integer status, Long startTime, Long endTime) {
        return ordersMapper.selectOrdersDiscDtoCount(pointId, status, startTime, endTime);
    }

    @Override
    public List<OrdersDistDto> selectOrdersDiscDtoUserList(Integer status, Long pointId, Long startTime, Long endTime) {
        List<OrdersDistDto> ordersDistDtoList = ordersMapper.selectOrdersDiscDtoUserList(status, pointId, startTime, endTime);
        //设置订单提成
        for (OrdersDistDto ordersDistDto : ordersDistDtoList
        ) {
            //商品提成
            BigDecimal ordersPercentage = ordersGoodsService.getOrdersPercentageByOrdersId(ordersDistDto.getOrdersId());
            //订单提成=配送费+商品提成
            ordersDistDto.setPercentage(ordersDistDto.getDistPrice().add(ordersPercentage));
        }
        return ordersDistDtoList;
    }


    @Override
    public List<OrderStatistics> statisticsOderEveryInCome() {
        return ordersMapper.statisticsOderEveryInCome();
    }

    @Override
    public OrderStatifyVo statifyOrderCountAll() {
        return ordersMapper.statifyOrderCountAll();
    }

    @Override
    public OrderStatifyVo orderStatifyToday() {
        return ordersMapper.orderStatifyToday();
    }

    @Override
    public List<OrderLineVo> statifyOrderLine() {
        return ordersMapper.statifyOrderLine();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean affirmTake(Long ordersId, Long userId) {

        //检验订单支付状态
        Orders orders = ordersCheckUtils.checkOrdersPayStatus(ordersId,userId);

        try {
            //如果骑手未确认送达，设置签收人
            if (!orders.getDistStatus().equals(OrdersDistStatusEnum.已送达.getValue())) {
                String receiver = "";
                if (orders.getDistType().equals(OrdersDistTypeEnum.配送.getValue())) {
                    OrdersAddress address = ordersAddressMapper.selectOrdersAddressByOrdersId(ordersId);
                    if (address != null && StringUtils.isNotEmpty(address.getConsignee())) {
                        receiver = address.getConsignee();
                    }
                }
                if (orders.getDistType().equals(OrdersDistTypeEnum.自取.getValue())) {
                    SysUser user = apiMemberMapper.selectMemberById(userId);
                    if (user != null && StringUtils.isNotEmpty(user.getNickName())) {
                        receiver = user.getNickName();
                    }
                }
                orders.setReceiver(receiver);
            }

            orders.setStatus(OrdersStatusEnum.已确认收货.getValue()); //设置订单状态为30=已确认收货
            orders.setAffirmTime(DateUtils.getNowDate());//设置确认收货时间
            int rows = this.updateOrders(orders);
            if (rows < 0) {
                throw new CustomException("更改订单状态失败");
            }

            //代付订单给用户账户打钱
            if (orders.getOrdersType().equals(OrdersTypeEnum.代付.getValue())){
                log.info("代付订单给用户 {} 加钱 {}",orders.getUserId(),orders.getPayPrice());

                UserAccount userAccount=new UserAccount();
                BigDecimal payPrice=orders.getPayPrice();
                //代扣付款比例
                String percent = (String) sysConfigService.selectConfigByKey("sys.paymentOnBehalfOf.percent");
                if(StringUtils.isEmpty(percent)){
                    percent="0.90";
                }
                payPrice = payPrice.multiply(new BigDecimal(percent)).setScale(2,BigDecimal.ROUND_HALF_UP);
                userAccount.setAccount(payPrice);
                userAccount.setUserId(userId);
                boolean bl=userAccountMapper.addUserAccountMoney(userAccount)>0;
                if (bl==false){
                    throw new CustomException("代付订单更改订单状态失败");
                }
                MessageAccountDTO dto =new MessageAccountDTO();
                dto.setUserId(userId);
                dto.setMoney(payPrice.toString());
                dto.setType(MQTypeEnum.ADD_ACCOUNT.getType());
                mqSendUtils.sendAsynMessage(dto);
            }
            //发送订单自动评价延时消息
            mqSendService.sendOrdersAutoEvaluateDelayMessage(orders.getOrdersNo());

            //发送消息，保存
            MessageOrdersMessageDTO ordersMessageDTO = new MessageOrdersMessageDTO();
            ordersMessageDTO.setType(MQTypeEnum.ORDERS_MESSAGE_JPUSH.getType());
            ordersMessageDTO.setUserType(UserTypeEnum.COURIER.getCode());
            ordersMessageDTO.setOrdersNo(orders.getOrdersNo());
            ordersMessageDTO.setMark("用户确认收货通知");
            ordersMessageDTO.setMessage("尊敬的骑手阁下,您的货物已被用户确认收货!");
            mqSendUtils.sendAsynMessage(ordersMessageDTO);

            return true;
        } catch (Exception e) {
            throw new CustomException("确认收货失败");
        }

    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean ordersCancel(Long ordersId, Long userId, String cancelRemark) {

        Orders orders = ordersMapper.selectOrdersByIdAndUserId(ordersId, userId);

        //校验订单状态
        if (orders == null) {
            log.error("订单不存在");
            throw new CustomException("订单不存在");
        }
        //订单状态不等于10=进行中
        if (!orders.getStatus().equals(OrdersStatusEnum.进行中.getValue())) {
            log.error("订单状态异常");
            throw new CustomException("订单状态异常");
        }

        if (orders.getShipStatus().equals(CommonEnum.STATUS_20.getValue())) {
            throw new CustomException("订单已发货，无法取消订单", ShowTypeEnum.用户.getValue());
        }
        //支付状态
        String payStatus = orders.getPayStatus();
        try {
            orders.setCancelTime(DateUtils.getNowDate());
            orders.setCancelRemark(cancelRemark);
            orders.setPayStatus(PayStatusEnum.已退款.getValue());
            orders.setStatus(OrdersStatusEnum.已取消.getValue());
            orders.setPayment(Constants.DEBUG ? new BigDecimal("0.01") : orders.getPayPrice());
            if (this.updateOrders(orders) < 1) {
                return false;
            }
        } catch (Exception e) {
            throw new CustomException("订单取消失败", ShowTypeEnum.用户.getValue());
        }
        //库存恢复
        goodsKeepService.addKeepNum(orders);
        //发送消息，保存
        MessageOrdersMessageDTO ordersMessageDTO = new MessageOrdersMessageDTO();
        ordersMessageDTO.setType(MQTypeEnum.ORDERS_MESSAGE_JPUSH.getType());
        ordersMessageDTO.setUserType(UserTypeEnum.MEMBER.getCode());
        ordersMessageDTO.setOrdersNo(orders.getOrdersNo());
        ordersMessageDTO.setMark("订单取消通知");
        ordersMessageDTO.setMessage("尊敬的用户，您的订单" + orders.getOrdersNo() + "已取消！");
        mqSendUtils.sendAsynMessage(ordersMessageDTO);

        //如果订单未支付或支付价格为0
        if (!payStatus.equals(CommonEnum.STATUS_20.getValue())
                || orders.getPayPrice().compareTo(new BigDecimal(0)) == 0) {
            return true;
        }

        //退款
        try {
            if (orders.getPayType().equals(PayTypeEnum.FREEPAY.getCode())) {
                return true;
            } else if (orders.getPayType().equals(PayTypeEnum.ALIPAY.getCode())) {
//                aliPayService.refund(orders.getOrdersNo(), Constants.DEBUG ? new BigDecimal("0.01") : orders.getPayPrice());
                aliPayService.refund(orders.getOrdersNo(), orders.getPayPrice());
            } else if (orders.getPayType().equals(PayTypeEnum.WXPAY.getCode())) {
//                wxPayService.refund(orders.getOrdersNo(), Constants.DEBUG ? new BigDecimal("0.01") : orders.getPayPrice());
                wxPayService.refund(orders.getOrdersNo(), orders.getPayPrice());
            } else {
                log.error("不支持的退款方式");
                throw new CustomException("不支持的退款方式");
            }
        } catch (Exception e) {
            log.error("退款失败 {} ",e.getMessage());
            throw new CustomException("退款失败", ShowTypeEnum.用户.getValue());
        }
        //消费记录
        userConsumeService.addUserConsume(userId, orders.getPayPrice(), ordersId, UserConsumeEnum.订单退款, "+");
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean ordersRefund(Long ordersId, Long userId) {

        Orders orders =ordersCheckUtils.checkOrdersPayStatus(ordersId,userId);
        //优惠金额
        BigDecimal reducePrice = new BigDecimal(0);


        List<OrdersGoods> ordersGoodsList = ordersGoodsMapper.selectOrderGoodListByOrdersId(ordersId);
        try {
            int rows = 0;
            for (OrdersGoods ordersGoods : ordersGoodsList
            ) {
                ordersGoods.setDiscountStatus("1");
                //订单商品折扣价格=商品成交价格*商品数量
                BigDecimal discountPrice = ordersGoods.getGoodsPrice().multiply(new BigDecimal(ordersGoods.getGoodsNum()));
                ordersGoods.setDiscountPrice(discountPrice);
                if (ordersGoodsMapper.updateOrdersGoods(ordersGoods) < 1) {
                    continue;
                }
                reducePrice = reducePrice.add(discountPrice);
                rows++;
            }
            if (rows < 1) {
                return false;
            }
        } catch (Exception e) {
            throw new CustomException("计算退款金额失败");
        }
        try {
            orders.setReducePrice(reducePrice);
            orders.setPayPrice(orders.getPayPrice().subtract(reducePrice));
            if (this.updateOrders(orders) < 1) {
                return false;
            }
        } catch (Exception e) {
            throw new CustomException("更新订单金额失败");
        }
        try {
            if (orders.getPayType().equals(PayTypeEnum.ALIPAY.getCode())) {
                aliPayService.refund(orders.getOrdersNo(), Constants.DEBUG ? new BigDecimal("0.01") : reducePrice);
            }
            if (orders.getPayType().equals(PayTypeEnum.WXPAY.getCode())) {
                wxPayService.refund(orders.getOrdersNo(), Constants.DEBUG ? new BigDecimal("0.01") : reducePrice);
            }
        } catch (Exception e) {
            log.error(ordersId + "退款失败{}" + e.getMessage());
            throw new CustomException("退款失败");
        }
        //消费记录
        userConsumeService.addUserConsume(orders.getUserId(), reducePrice, orders.getOrdersId(), UserConsumeEnum.订单退款, "+");
        return true;
    }


    @Override
    public Orders selectOrdersByDefaultUserId(Long userId) {
        return ordersMapper.selectOrdersByDefaultUserId(userId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refundDist(Orders orders) {
        SysUser oldUser = apiMemberMapper.selectMemberById(orders.getUserId());
        //拒绝退款处理
        if (orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue()) && orders.getDistStatus().equals(CommonEnum.STATUS_50.getValue())) {
            try {
                if (orders.getPayType().equals(PayTypeEnum.ALIPAY.getCode())) {
                    aliPayService.refund(orders.getOrdersNo(), orders.getPayPrice());
                } else if (orders.getPayType().equals(PayTypeEnum.WXPAY.getCode())) {
                    wxPayService.refund(orders.getOrdersNo(), orders.getPayPrice());
                } else {
                    throw new CustomException("退款失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new CustomException("退款失败");
            }

            //消费记录
            userConsumeService.addUserConsume(orders.getUserId(), orders.getPayPrice(), orders.getOrdersId(), UserConsumeEnum.订单退款, "+");

            orders.setPayStatus(CommonEnum.STATUS_40.getValue());
            orders.setStatus(OrdersStatusEnum.已关闭.getValue());
            updateOrders(orders);

////            //推送消息
//            PushPayload pushPayload1 = MessagePushUtils.push(Audience.alias(oldUser.getPhonenumber()), "无骑手接单，已退款", null);
////            //TODO（开始推送）
//            MessagePushUtils.sendPushTryCatch(JpushUserEnum.客户端,pushPayload1);
        }
    }

    //@Override


    @Override
    public OrdersInfoDto setOrdersInfo(Orders orders) {
        if (orders != null) {
            orders.setOrdersAddress(ordersAddressMapper.selectOrdersAddressByOrdersId(orders.getOrdersId()));
            OrdersPoint ordersPoint = ordersPointMapper.selectOrdersPointByOrdersId(orders.getOrdersId());
            if (null != ordersPoint) {
                Long pointId = ordersPoint.getPointId();
                DistributionPoint distributionPoint = distributionPointService.selectDistributionPointById(pointId);
                if (null != distributionPoint) {
                    DistributionPointImgVO vo = new DistributionPointImgVO();
                    vo.setDistributionPointWxImg(distributionPoint.getPointImg());
                    String listImg = distributionPoint.getListImg();
                    List<String> list = new ArrayList<>();
                    if (StringUtils.isNotEmpty(listImg)) {
                        String[] imgs = listImg.split(",");
                        list = Arrays.asList(imgs);
                    }
                    vo.setDistributionPointShopImg(list);
                    ordersPoint.setDistributionPointImgVO(vo);
                }
            }
            orders.setOrdersPoint(ordersPoint);
            List<OrdersGoods> list = ordersGoodsService.selectOrderGoodListByOrdersId(orders.getOrdersId());
            orders.setGoodsList(list);
            orders.setGiftList(ordersGiftService.selectOrdersGiftListByOrdersId(orders.getOrdersId()));
            orders.setCourier(ordersCourierService.selectOrdersCourierByOrdersId(orders.getOrdersId()));
            orders.setShop(shopService.selectShopById(orders.getShopId()));
        }
        return OrdersInfoDto.news(orders);
    }

    @Override
    public List<PrintData> selectPrintDataList(Long shopId) {
        return ordersMapper.selectPrintDataList(shopId);
    }


    @Override
    public boolean updateOrdersPrintStatus(Orders orders, String beforeStatus, String afterStatus) {
        if(null==orders){
            log.error("订单不存在");
            throw new CustomException("订单不存在");
        }
        if(StringUtils.isEmpty(orders.getPayStatus())||StringUtils.isEmpty(beforeStatus)){
            log.error("printStatus is null");
            throw new CustomException("订单打印状态为空");
        }
        if(!orders.getPrintStatus().equals(beforeStatus)||orders.getPrintStatus().equals(afterStatus)){
           return true;
        }
        Orders updateOrders=new Orders();
        updateOrders.setOrdersId(orders.getOrdersId());
        updateOrders.setPrintStatus(afterStatus);
        updateOrders.setUpdateTime(DateUtils.getNowDate());
        return ordersMapper.updateOrdersPrintStatus(updateOrders)>0;
    }


    @Override
    public String getOrdersPrintStatus(Orders orders) {
        return ordersMapper.getOrdersPrintStatus(orders);
    }





    @Override
    public Boolean checkPlaceAnOrder(Long userId) {
        if (null == userId) {
            throw new CustomException("userId 不能为空");
        }
        Long count = ordersMapper.getOrdersCountByUserId(userId);
        if (null == count) {
            return false;
        }
        return count > 1;
    }

    @Override
    public int updateFreePayOrdersPayStatus(Long ordersId) {
        Orders orders = this.selectOrdersById(ordersId);
        if (null == orders) {
            log.error("ID为" + ordersId + "的订单不存在");
            throw new CustomException("订单不存在");
        }
        if (orders.getPayPrice().compareTo(new BigDecimal(0)) != 0) {
            return 0;
        }
        if (!orders.getPayStatus().equals(CommonEnum.STATUS_10.getValue())) {
            return 0;
        }
        orders.setPayStatus(CommonEnum.STATUS_20.getValue());
        orders.setPayType(PayTypeEnum.FREEPAY.getCode());
        orders.setPayTime(DateUtils.getNowDate());
        //添加商户超时接单时间
        orders.setDistShopOutTime(getDistShopOutTime(orders));
        return this.updateOrders(orders);

    }

    @Override
    public void updateOrdersPayStatusAndSendMessages(Long ordersId) {

        if (this.updateFreePayOrdersPayStatus(ordersId) < 1) {
            return;
        }
        Orders orders = this.selectOrdersById(ordersId);
        //发送限购商品购买记录消息
        mqSendService.sendUserGoodsLimitAsynMessage(orders.getOrdersNo());
        //发送订单自动接单消息
        mqSendService.sendOrdersAutoTakeAsynMessage(orders.getOrdersNo());
        //发送订单超时打印消息
        mqSendService.sendPrintStatusDelayMessage(orders.getOrdersNo());
        //发送订单自动发货消息
        //mqSendService.sendOrdersAutoShipDelayMessage(orders.getOrdersNo());
    }




    @Override
    public void setPrice(AddOrdersInfoDto ordersInfoDto, BigDecimal totalPrice, BigDecimal reducePrice, String distType) {

        //配送费
        BigDecimal distPrice = ordersDistService.getDistPrice(totalPrice, distType);
        if (OrdersTypeEnum.捶一捶.getValue().equals(ordersInfoDto.getOrdersType())){
            reducePrice = reducePrice.add(distPrice);
        }
        //支付价格=商品总价-优惠价格+配送费
        BigDecimal payPrice = totalPrice.subtract(reducePrice);
        String ordersType = ordersInfoDto.getOrdersType();
        if (!StringUtils.isEmpty(ordersType)){
            if (OrdersTypeEnum.货到付款.getValue().equals(ordersType)){
                //货到付款比例
                String percent = (String) sysConfigService.selectConfigByKey("sys.cashOnDelivery.percent");
                if (StringUtils.isEmpty(percent)){
                    percent="0.05";
                }
                payPrice = payPrice.multiply(new BigDecimal(percent)).setScale(2,BigDecimal.ROUND_HALF_UP);
            }
        }
        payPrice = payPrice.add(distPrice);
        //订单总价
        ordersInfoDto.setTotalPrice(totalPrice.setScale(2, BigDecimal.ROUND_HALF_DOWN));
        //配送费
        ordersInfoDto.setDistPrice(distPrice.setScale(2, BigDecimal.ROUND_HALF_DOWN));
        //优惠价格
        ordersInfoDto.setReducePrice(reducePrice.setScale(2, BigDecimal.ROUND_HALF_DOWN));
        //支付价格
        ordersInfoDto.setPayPrice(payPrice.setScale(2, BigDecimal.ROUND_HALF_DOWN));
    }

    @Override
    public void setPrice(AddOrdersInfoDto ordersInfoDto, BigDecimal totalPrice) {


        //订单总价
        ordersInfoDto.setTotalPrice(totalPrice.setScale(2, BigDecimal.ROUND_HALF_DOWN));

        //支付价格
        ordersInfoDto.setPayPrice(totalPrice.setScale(2, BigDecimal.ROUND_HALF_DOWN));
    }

    @Override
    public boolean ordersSingleRefund(Long orderId, Long userId) {

        Orders orders = ordersMapper.selectOrdersByIdAndUserId(orderId, userId);
        if (orders == null) {
            throw new CustomException("订单不存在");
        }
        return ordersMapper.ordersSingleRefund(orders) >= 1;
    }


    /**
     * 根据订单支付时间获取店铺接单超时时间
     *
     * @param orders
     * @return
     */
    private Date getDistShopOutTime(Orders orders) {
        //添加商户超时接单时间
        Calendar distShopOutTime = Calendar.getInstance();
        distShopOutTime.setTime(orders.getPayTime());
        String outTime = sysConfigService.selectConfigByKey("sys.orders.shopOutTime").toString();
        distShopOutTime.add(Calendar.MINUTE, Integer.parseInt(outTime));
        return distShopOutTime.getTime();

    }

    @Override
    public boolean updateOrdersEndStatus(Long ordersId) {
        Orders orders = ordersMapper.selectOrdersById(ordersId);
        if (null == orders) {
            throw new CustomException("订单不存在");
        }
        if (orders.getStatus().equals(OrdersStatusEnum.已完结.getValue())) {
            return true;
        }
        orders.setEvalStatus(CommonEnum.STATUS_20.getValue());
        orders.setEvalTime(DateUtils.getNowDate());
        orders.setStatus(OrdersStatusEnum.已完结.getValue());
        int rows = this.updateOrders(orders);
        if (rows < 1) {
            log.error("更改订单完结状态失败");
            throw new CustomException("更改订单完结状态失败", ShowTypeEnum.用户.getValue());
        }
        return true;
    }

    @Override
    public boolean ordersShip(String value) {
        String ordersNo=value;
        boolean bl=JSONUtil.isJsonObj(ordersNo);
        if (bl){
            final cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(ordersNo);
            int type=jsonObject.getInt("type");
            if (type==2){
                ordersNo=jsonObject.getStr("orderNo");
            }else {
                throw  new CustomException("当前二维码无法识别");
            }
        }
        //根据订单编号查询订单
        Orders orders=ordersMapper.selectOrdersByOrdersNo(ordersNo);
        if (orders == null){
            throw new CustomException("订单不存在！");
        }
        if(orders.getShipStatus().equals(CommonEnum.STATUS_20.getValue())){
            throw new CustomException("重复发货");
        }
        if (!orders.getStatus().equals(OrdersStatusEnum.进行中.getValue())){
            throw new CustomException("订单已取消");
        }
        if (!orders.getPayStatus().equals(CommonEnum.STATUS_20.getValue())){
            throw new CustomException("订单未支付");
        }
        if (!orders.getDistShopStatus().equals(CommonEnum.STATUS_20.getValue())){
            throw new CustomException("店铺未接单");
        }
        if(!orders.getPrintStatus().equals(CommonEnum.STATUS_20.getValue())){
            throw new CustomException("订单未打印");
        }

        //设置订单发货状态为20=已发货
        orders.setShipStatus(CommonEnum.STATUS_20.getValue());
        orders.setShipTime(DateUtils.getNowDate());
        int rows=ordersMapper.updateOrders(orders);
        if(rows<=0){
           throw new CustomException("发货失败");
        }
        //发送订单自动确认收货延时消息
        mqSendService.sendOrdersAutoAffirmDelayMessage(ordersNo);
        //发送商品统计消息
        mqSendService.sendPointSaleRecordAsynMessage(ordersNo);
        // 推送订单消息
        MessageOrdersMessageDTO ordersMessageDTO=new MessageOrdersMessageDTO();
        ordersMessageDTO.setType(MQTypeEnum.ORDERS_MESSAGE_JPUSH.getType());
        ordersMessageDTO.setUserType(UserTypeEnum.MEMBER.getCode());
        ordersMessageDTO.setOrdersNo(orders.getOrdersNo());
        ordersMessageDTO.setMark("订单发货通知");
        ordersMessageDTO.setMessage("尊敬的用户，您的订单"+ordersNo+"已发货");
        mqSendUtils.sendAsynMessage(ordersMessageDTO);

        try {
            String config = (String) sysConfigService.selectConfigByKey("sys.share.withdrawal");
            JSONObject jsonObject = JSONObject.parseObject(config);
            String open = jsonObject.getString("open");
            if ("0".equals(open)){
                log.error("--------分享提现活动未开启-------");
                throw new CustomException("分享提现活动未开启");
            }
            String minMoney = jsonObject.getString("minMoney");
            String maxMoney = jsonObject.getString("maxMoney");
            String limitOrdersPrice = jsonObject.getString("limitOrdersPrice");
            if (StringUtils.isEmpty(minMoney)){
                log.error("分享提现的钱minMoney={}",minMoney);
                throw new CustomException("分享提现的minMoney为空");
            }
            if (StringUtils.isEmpty(maxMoney)){
                log.error("分享提现的钱maxMoney={}",maxMoney);
                throw new CustomException("分享提现的maxMoney为空");
            }
            if (StringUtils.isEmpty(limitOrdersPrice)){
                log.error("分享提现的钱limitOrdersPrice={}",limitOrdersPrice);
                throw new CustomException("分享提现的限制金额为空");
            }
            BigDecimal minMoneyO = new BigDecimal(minMoney);
            BigDecimal maxMoneyO = new BigDecimal(maxMoney);
            BigDecimal limitOrdersPriceO = new BigDecimal(limitOrdersPrice);
            String money = "0";
            if (orders.getPayPrice().compareTo(limitOrdersPriceO) >= 0){
                money = maxMoneyO.toString();
            }
            if (orders.getPayPrice().compareTo(limitOrdersPriceO) <0){
                money = minMoneyO.toString();
            }
            if (orders.getPayPrice().compareTo(new BigDecimal("0")) <= 0){
                throw new CustomException("提现金额不存在");
            }
            Example example = new Example(ShareOrders.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("ordersId",orders.getOrdersId());
            ShareOrders shareOrders = shareOrdersMapper.selectOneByExample(example);
            if (shareOrders == null){
                log.info("不是分享提现订单 ordersId={}",orders.getOrdersId());
                throw new CustomException("不是分享提现订单");
            }

            SysUser sysUser = sysUserService.selectUserById(shareOrders.getCourierId());
            if (sysUser == null){
                throw new CustomException("分享骑手用户为空sysUser=Null");
            }
            Long userId = sysUserService.selectUserIdByPhoneNumberAndUserType(sysUser.getPhonenumber(), UserTypeEnum.MEMBER.getCode());
            if (userId == null){
                throw new CustomException("分享用户id为空userId=Null");
            }
            System.out.println("----------发送分享提现消息---------------");
            mqSendService.sendShareMoneyAsynMessage(userId,money);
            shareOrders.setIsSuccess("1");
            shareOrders.setShareMoney(new BigDecimal(money));
            shareOrdersMapper.updateByPrimaryKeySelective(shareOrders);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }

        return true;
    }

    @Override
    public List<String> listOrdersNoByTime(String startTime,String endTime) {
        return ordersMapper.listOrdersNoByTime(startTime,endTime);
    }

    @Override
    public boolean ordersAutoShip(String ordersNo) {
        boolean b = ordersShip(ordersNo);
        return b;
    }

    @Override
    public boolean updateOrdersPayment(String ordersNo,String money){
        Orders orders=ordersMapper.selectOrdersByOrdersNo(ordersNo);
        if(null==orders){
            log.error("订单不存在");
            throw new CustomException("订单不存在");
        }
        BigDecimal payment;
        try{
            payment=new BigDecimal(money);
        }catch (Exception e){
            log.error("退款金额不正确");
            throw new CustomException("退款金额不正确");
        }
        Orders updateOrders=new Orders();
        updateOrders.setOrdersId(orders.getOrdersId());
        updateOrders.setPayment(payment);
        updateOrders.setUpdateTime(DateUtils.getNowDate());
        return ordersMapper.updateOrdersPayment(updateOrders)>0;
    }

    public BigDecimal getOrdersTotalPrice(Date startTime, Date endTime){
        return ordersMapper.getOrdersTotalPrice(ApiUtils.getUserId(),startTime,endTime);
    }

    @Override
    public boolean updateOrderspointCommission(Long orderId,String pointPrice, String pointCommission) {
        return ordersMapper.updateOrdersPointCommission(orderId,pointPrice,pointCommission)>0;
    }

    @Override
    public List<OrderStatisticsVO> listOrderStatistics(OrderStatisticsDTO dto) {

        return ordersMapper.listOrderStatistics(dto);
    }

    @Override
    public boolean updatePaymentOnBehalfOfType(String ordersNo) {

        return ordersMapper.updatePaymentOnBehalfOfType(ordersNo)>0;
    }

}
